// algorithm
// Created by FanGccU on 2025/6/23.
// 容器工具类

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>

using namespace std;

vector<int> num1 = {20, 40, 30, 50, 10, 60, 90, 80, 70};

/**
 * sort
 * 不稳定排序
 */
void func1() {
    // 排序（不稳定）
    sort(num1.begin(), num1.end());

    cout << "sort value :\t";
    for (int i: num1) {
        cout << i << "\t";
    }
    cout << endl;;
}

struct Book {
    int id;
    string title;
    int sort;
};

bool compareBySort(const Book &book1, const Book &book2) {
    return book1.sort < book2.sort;
}

vector<Book> books = {
    {1, "C++", 1},
    {2, "C", 2},
    {3, "Python", 3},
    {4, "Java", 4},
    {5, "JavaScript", 5},
    {6, "php", 5}
};

/**
 * sort 和 stable_sort 的区别
 */
void func2() {
    // 排序。sort = 不稳定排序，JavaScript 和 php 的 sort 是一样的，排序时可能混淆
    sort(books.begin(), books.end(), compareBySort);
    cout << "sort values :\t";
    for (const Book &i: books) {
        cout << "title:\t" << i.title << " sort:\t" << i.sort << "\t";
    }
    cout << endl;

    // 稳定排序。排序结果始终一致
    stable_sort(books.begin(), books.end(), compareBySort);

    cout << "stable_sort values :\t";
    for (const Book &i: books) {
        cout << "title:\t" << i.title << " sort:\t" << i.sort << "\t";
    }
    cout << endl;
}

/**
 * find 查询第一个匹配的值
 * find_if 查询第一个满足条件的值
 */
void func3() {
    auto it = find(num1.begin(), num1.end(), 50);
    if (it != num1.end()) {
        cout << "find :\t" << *it << endl;
    } else {
        cout << "not find value" << endl;
    }

    // 匹配第一个大于50的值
    auto it2 = find_if(num1.begin(), num1.end(), [](const int x) { return x > 50; });
    cout << *it2 << endl;
}

/**
 * copy 将源容器的数据复制到目标容器中
 */
void copyFunc() {
    vector<int> num1 = {10, 20, 30, 40, 50};

    // copy 至数组
    int num2[5];
    copy(num1.begin(), num1.end(), num2);
    cout << "num2 values :\t";
    for (const int i: num2) {
        cout << i << "\t";
    }
    cout << endl;

    // copy 至 vector
    vector<int> num3;
    copy(num1.begin(), num1.end(), back_inserter(num3));
    cout << "num3 values :\t";
    for (const int i: num3) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * equal 比较两个容器是否相等
 */
void equalsFunc() {
    vector<int> vec1 = {1, 2, 3, 4, 5};
    vector<int> vec2 = {1, 2, 3, 4, 5};

    bool isEquals = equal(vec1.begin(), vec1.end(), vec2.begin());
    if (isEquals) {
        cout << "equal" << endl;
    } else {
        cout << "not equal" << endl;
    }
}


/**
 * 反转
 */
void reverseFunc() {
    vector<int> num1 = {10, 20, 30, 40, 50};
    reverse(num1.begin(), num1.end());

    cout << "reverse value： \t";
    for (const int i: num1) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * 覆盖范围内的值
 */
void fillFunc() {
    vector<int> v = {1, 2, 3, 4, 5};

    // 将所有元素赋值为10
    fill(v.begin(), v.end(), 10);

    cout << "fill value： \t";
    for (const int i: v) {
        cout << i << "\t";
    }
    cout << endl;

    // 覆盖指定范围，将第二位至倒数第二位赋值为20
    fill(v.begin() + 1, v.end() - 1, 20);

    cout << "fill value： \t";
    for (const int i: v) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * 替换
 */
void replaceFunc() {
    vector<int> v = {1, 2, 3, 4, 5};
    // 将 3 替换为 10
    replace(v.begin(), v.end(), 3, 10);

    cout << "replace value： \t";
    for (const int i: v) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * 排列算法
 * 根据元素值大小顺序向下排列出各种组合
 *
 */
void permutationFunc() {
    vector<int> vec = {1, 2, 3};
    do {
        for (int v: vec) {
            cout << v << "\t";
        }
        cout << endl;
    } while (next_permutation(vec.begin(), vec.end()));

    // prev_permutation(vec.begin(),vec.end()); 向上排列
}

/**
 * 将两个有序的集合合并为一个有序集合
 */
void mergeFunc() {
    vector<int> num1 = {1, 3, 5, 7, 9};
    vector<int> num2 = {2, 4, 6, 8, 10};
    vector<int> results(10); // 结果集合在声明时必须定义长度

    merge(num1.begin(), num1.end(), num2.begin(), num2.end(), results.begin());

    cout << "values :";
    for (int i: results) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * 集合算法
 */
void unionFunc() {
    vector<int> num1 = {1, 3, 5, 7, 9};
    vector<int> num2 = {2, 9, 6, 1, 10};

    vector<int> unionResults(10);
    vector<int> interResults(10);
    vector<int> diffResults(10);

    // 原集合必须是有序的
    sort(num1.begin(), num1.end());
    sort(num2.begin(), num2.end());

    // set_union 计算两个集合的并集
    const auto unionIndex = set_union(num1.begin(), num1.end(), num2.begin(), num2.end(), unionResults.begin());
    // 重新设置 results 的长度，因为 results 的初始长度是10，但是计算后的并集长度只有8位，超出的长度会默认补充0
    unionResults.resize(unionIndex - unionResults.begin());

    cout << "两个集合的并集：\t";
    for (const int it: unionResults) {
        cout << it << "\t";
    }
    cout << endl;

    // set_intersection 获取两个集合的交集
    const auto interIndex = set_intersection(num1.begin(), num1.end(), num2.begin(), num2.end(), interResults.begin());
    interResults.resize(interIndex - interResults.begin());
    cout << "两个集合的交集：\t";
    for (const int it: interResults) {
        cout << it << "\t";
    }
    cout << endl;

    // set_difference 获取两个集合的差集（ 在 num1 中存在，在 num2 中不存在的数据 ）
    const auto diffIndex = set_difference(num1.begin(), num1.end(), num2.begin(), num2.end(), diffResults.begin());
    diffResults.resize(diffIndex - diffResults.begin());
    cout << "两个集合的差集：\t";
    for (const int it: diffResults) {
        cout << it << "\t";
    }
    cout << endl;
}

/**
 * 计算容器总和
 */
void sunFunc() {
    vector<int> vec = {1, 2, 3, 4, 5};
    const int sum = accumulate(vec.begin(), vec.end(), 0);
    cout << "vec sum value :\t" << sum << endl;
}

/**
 * 对每个元素进行操作
 */
void optFunc() {
    vector<int> vec = {1, 2, 3, 4, 5};
    for_each(vec.begin(), vec.end(), [](int &x) { x += 1; });

    cout << "对每个元素进行自增：";
    for (const int i: vec) {
        cout << i << "\t";
    }
    cout << endl;
}

/**
 * 获取最大值和最小值
 */
void getMaxAndMinFunc() {
    vector<int> vec = {1, 2, 3, 4, 5};
    const auto minValue = min_element(vec.begin(), vec.end());
    const auto maxValue = max_element(vec.begin(), vec.end());

    cout << "vec max value :" << *maxValue << endl;
    cout << "vec min value :" << *minValue << endl;
}


int main(int argc, char *argv[]) {
    // func1();
    // func2();
    // func3();
    // copyFunc();
    // equalsFunc();
    // reverseFunc();
    // fillFunc();
    // replaceFunc();
    // permutationFunc();
    // mergeFunc();
    // unionFunc();
    // sunFunc();
    // optFunc();
    getMaxAndMinFunc();
}
